﻿#pragma once
#include <atomic>
#include <cstdint>
#include "DeviceInterface.h"
#include "Network.h"
#include "pch.h"
#include <string>
#include <unordered_map>

uint16_t CRC16_X25(uint8_t *data, uint16_t len);
std::string convert_gb2312_to_utf8(const std::string& input);

class ChengGuRsuClient : public DeviceInterface {

    std::unordered_map<uint8_t,std::string> vehicle_type_map = {
        {0x01,"一类客车"},
        {0x02,"二类客车"},
        {0x03,"三类客车"},
        {0x04,"四类客车"},
        {0x05,"五类客车"},
        {0x06,"六类客车"},
        {0x07,"自定义"},
        {0x08,"自定义"},
        {0x09,"自定义"},
        {0x0A,"自定义"},
        {0x0B,"一类货车"},
        {0x0C,"二类货车"},
        {0x0D,"三类货车"},
        {0x0E,"四类货车"},
        {0x0F,"五类货车"},
        {0x10,"六类货车"},
        {0x11,"自定义"},
        {0x12,"自定义"},
        {0x13,"自定义"},
        {0x14,"自定义"},
        {0x15,"一类专项作业车"},
        {0x16,"二类专项作业车"},
        {0x17,"三类专项作业车"},
        {0x18,"四类专项作业车"},
        {0x19,"五类专项作业车"},
        {0x1A,"六类专项作业车"},
    };

    std::unordered_map<uint8_t, std::string> color_map = {
        {0x00,"蓝色"},
        {0x01,"黄色"},
        {0x02,"黑色"},
        {0x03,"白色"},
        {0x04,"渐变绿色"},
        {0x05,"蓝黄拼色"},
        {0x06,"蓝白渐变色"},
        {0x07,"绿双拼色"},
    };


#pragma pack(push, 1)
    struct DataFrameHeader {
        uint16_t STX = 0xFFFF;
        uint8_t VER = 0x00;
        uint8_t SEQ = 0x01;
        uint16_t LEN_H = 0x00;
        uint16_t LEN_L = 0x00;
    };

    struct MEC_RsuInitFrame {
        uint8_t CmdType = 0xC0;
        uint32_t UnixTime;
        uint8_t PLLChannelID;
    };

    struct MEC_AckFrame {
        uint8_t CmdType = 0xC1;
        uint8_t MACID[4];
    };

    struct MEC_HeartbeatFrame {
        uint8_t CmdType = 0xCB;
    };

    //-----------------------------------------------

    struct RSU_DeviceStatusFrame {
        uint8_t CmdType = 0xB0;
        uint8_t RSUMasterInitStatus;
        uint8_t RSUSlaverInitStatus;
        uint16_t RSUVersion;
        uint8_t RSUManuID;
        uint8_t RSUID[3];
    };

    struct RSU_HeartbeatFrame {
        uint8_t FrameType = 0xBB;
        uint8_t RSUStatus;
        uint8_t Reserve[4];
    };

    struct RSU_VehicleInformationFrame {
        uint8_t FrameType = 0xB4;
        uint8_t MACID[4];
        uint8_t ErrorCode;
        uint8_t VehiclePlate[12]; //全牌照（汉字+字母+数字）信息， 采用字符型存储，汉字采用 GB2312
                                  //码，如“京”编码为“BEA9”，牌照信息不足 12 字 节，后补 0x00
        uint8_t VehicleType;
        uint8_t Colour;
        uint16_t ObuStatus;
    };

#pragma pack(pop)

    class FrameSequenceNumber {
    public:
        FrameSequenceNumber()
            : _seq_num(0) {}

        uint8_t get() {
            _seq_num.fetch_add(1);
            if (_seq_num.load() > 9) {
                _seq_num.store(1);
            }
            return _seq_num.load();
        }



        

    private:
        std::atomic_uint8_t _seq_num;
    };

public:
    virtual void Init(std::shared_ptr<DeviceInfo> info);
    virtual void Start();
    virtual void Stop();

private:
    void OnConnected();
    void OnReceiveData(const toolkit::Buffer::Ptr &buf);
    void ParseData();

private:
    std::shared_ptr<TcpClient> _client = nullptr;
    std::string _buffer = "";
    FrameSequenceNumber _seq_num;
    std::shared_ptr<DeviceInfo> _device_info = nullptr;
    bool _send_init_frame = false;
};